package com.gitee.cirnochat.user.controller;


import com.gitee.cirnochat.common.annotation.AuthCheck;
import com.gitee.cirnochat.common.model.vo.resp.PageVo;
import com.gitee.cirnochat.common.model.vo.resp.Result;
import com.gitee.cirnochat.common.utils.RequestUtils;
import com.gitee.cirnochat.file.model.vo.resp.FileUploadResponse;
import com.gitee.cirnochat.file.service.FileManager;
import com.gitee.cirnochat.user.model.vo.req.user.UserEmailResetPasswordRequest;
import com.gitee.cirnochat.user.model.vo.req.user.UserEmailSetPasswordRequest;
import com.gitee.cirnochat.user.model.vo.req.user.UserInfoUpdateRequest;
import com.gitee.cirnochat.user.model.vo.req.user.UserOnlineStatusUpdateRequest;
import com.gitee.cirnochat.user.model.vo.resp.UserVo;
import com.gitee.cirnochat.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.headers.Header;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Tag(name = "用户信息接口", description = "用户信息相关API")
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserInfoController {

    private final UserService userService;
    private final FileManager fileManager;

    //region 查询操作
    /**
     * 获取用户的基本信息
     * @param request
     * @return
     */
    @Operation(summary = "获取用户的个人基本信息", description = "获取用户的个人基本信息")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = UserVo.class)
            ),
            headers = {
                    @Header(name = "Authorization", description = "认证信息", required = true)
            }
    )
    @Parameter(name = "Authorization", description = "认证信息", required = true , in = ParameterIn.HEADER)
    @Parameter(name = "X-Device-Id", description = "设备ID", required = true , in = ParameterIn.HEADER)
    @AuthCheck
    @GetMapping("/profile")
    public Result<UserVo> getUserInfoByToken(HttpServletRequest request) {
        Long userId = RequestUtils.getUserId(request);
        return Result.success(userService.getUserInfoById(userId));
    }

    /**
     * 获取用户的基本信息
     * @param request
     * @return
     */
    @Operation(summary = "获取用户的基本信息通过ID", description = "获取用户的个人基本信息通过ID")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = UserVo.class)
            ),
            headers = {
                    @Header(name = "Authorization", description = "认证信息", required = true)
            }
    )
    @Parameter(name = "Authorization", description = "认证信息", required = true , in = ParameterIn.HEADER)
    @Parameter(name = "X-Device-Id", description = "设备ID", required = true , in = ParameterIn.HEADER)
    @AuthCheck
    @GetMapping("/profile/{id}")
    public Result<UserVo> getUserInfoById(@PathVariable @Parameter(name = "id" , required = true , in = ParameterIn.PATH) Long id , HttpServletRequest request) {
        Long userId = RequestUtils.getUserId(request);
        return Result.success(userService.getUserInfoWithFriendRelById(id,userId));
    }

    @Operation(summary = "通过UUID搜索用户", description = "通过UUID精确搜索用户")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = UserVo.class)
            )
    )
    @GetMapping("/search/uuid")
    @AuthCheck
    @Parameter(name = "Authorization", description = "认证信息", required = true, in = ParameterIn.HEADER)
    @Parameter(name = "X-Device-Id", description = "设备ID", required = true , in = ParameterIn.HEADER)
    public Result<UserVo> searchByUUID(@NotBlank(message = "凭证不能为空") @Parameter(name = "uuid", in = ParameterIn.QUERY , required = true) @RequestParam(required = true) String uuid,
                                               HttpServletRequest request) {
        Long userId = RequestUtils.getUserId(request);
        return Result.success(userService.searchByUUID(userId,uuid));
    }





    @Operation(summary = "通过名称或邮箱搜索用户", description = "通过名称或邮箱搜索用户")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = UserVo.class)
            )
    )
    @GetMapping("/search/keyword")
    @AuthCheck
    @Parameter(name = "Authorization", description = "认证信息", required = true, in = ParameterIn.HEADER)
    @Parameter(name = "X-Device-Id", description = "设备ID", required = true , in = ParameterIn.HEADER)
    public Result<PageVo<UserVo>> searchByName(@NotBlank(message = "搜索信息不能为空") @Parameter(name = "keyword", in = ParameterIn.QUERY , required = true) @RequestParam(required = true) String keyword,
                                               @Parameter(description = "页码",  example = "1") @RequestParam(defaultValue = "1", required = false) int page,
                                               @Parameter(description = "每页数量", example = "10") @RequestParam(defaultValue = "10" , required = false) int size,
                                               @Parameter(description = "排序方式 1:升序 2:降序", example = "2")  @RequestParam(defaultValue = "2",required = false) int sort,
                                               HttpServletRequest request) {
        Long userId = RequestUtils.getUserId(request);
        return Result.success(userService.searchByKeyword(userId,keyword,page,size,sort));
    }

    //endregion


    //region 更新操作

    /**
     * 更新用户基本信息
     * @param req 用户信息更新请求
     * @param request 请求
     * @return
     */
    @Operation(summary = "更新用户基本信息", description = "更新用户基本信息，需要更新什么字段则传什么字段，不需要更新的字段不传")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = Result.class)
            ),
            headers = {
                    @Header(name = "Authorization", description = "认证信息", required = true)
            }
    )
    @Parameter(name = "Authorization", description = "认证信息", required = true , in = ParameterIn.HEADER)
    @Parameter(name = "X-Device-Id", description = "设备ID", required = true , in = ParameterIn.HEADER)
    @AuthCheck
    @PutMapping("/profile")
    public Result<Void> updateUserInfo(@Valid @RequestBody UserInfoUpdateRequest req,
                                       HttpServletRequest request) {
        Long userId = RequestUtils.getUserId(request);
        req.setUserId(userId);
        userService.updateUserInfo(req);
        return Result.success();
    }


    /**
     * 更新用户偏好在线状态
     * @param req 用户在线状态更新请求
     * @param request 请求
     * @return
     */
    @Operation(summary = "更新用户偏好在线状态", description = "更新用户在线显示状态，注意：如果当前用户在线状态为离线，则会决定用户将处于离线状态")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = Result.class)
            ),
            headers = {
                    @Header(name = "Authorization", description = "认证信息", required = true)
            }
    )
    @Parameter(name = "Authorization", description = "认证信息", required = true , in = ParameterIn.HEADER)
    @Parameter(name = "X-Device-Id", description = "设备ID", required = true , in = ParameterIn.HEADER)
    @AuthCheck
    @PutMapping("/prefer-status")
    public Result<Void> updateUserPreferStatus(@Valid @RequestBody UserOnlineStatusUpdateRequest req,
                                       HttpServletRequest request) {
        Long userId = RequestUtils.getUserId(request);
        userService.updateUserPreferStatus(req,userId);
        return Result.success();
    }


    @Operation(summary = "设置用户的密码", description = "设置用户的密码")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = Result.class)
            ),
            headers = {
                    @Header(name = "Authorization", description = "认证信息", required = true)
            }
    )
    @Parameter(name = "Authorization", description = "认证信息", required = true , in = ParameterIn.HEADER)
    @Parameter(name = "X-Device-Id", description = "设备ID", required = true , in = ParameterIn.HEADER)
    @AuthCheck
    @PutMapping("/set-password")
    public Result<Void> setPassword(@Valid @RequestBody UserEmailSetPasswordRequest req,
                                      HttpServletRequest request) {
        Long userId = RequestUtils.getUserId(request);
        userService.updateUserPassword(req,userId);
        return Result.success();
    }

    @Operation(summary = "重置用户的密码", description = "重置用户的密码")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = Result.class)
            ),
            headers = {
                    @Header(name = "Authorization", description = "认证信息", required = true)
            }
    )
    @PutMapping("/reset-password")
    public Result<Void> resetPassword(@Valid @RequestBody UserEmailResetPasswordRequest req) {
        userService.updateUserPassword(req);
        return Result.success();
    }

    /**
     * 上传图片作为头像
     *
     * @param file      上传文件
     * @param request           请求
     * @return {@link Result}<{@link FileUploadResponse}>
     */
    @PostMapping("/avatar")
    @Operation(summary = "上传头像", description = "上传图片作为用户头像")
    @ApiResponse(
            responseCode = "200",
            description = "成功",
            content = @Content(
                    mediaType = "application/json",
                    schema = @Schema(implementation = FileUploadResponse.class)
            )
    )
    @Parameter(name = "Authorization", description = "认证信息", required = true , in = ParameterIn.HEADER)
    @Parameter(name = "X-Device-Id", description = "设备ID", required = true , in = ParameterIn.HEADER)
    public Result<FileUploadResponse> uploadUserAvatar(@RequestPart(required = true) MultipartFile file, HttpServletRequest request) {
        Long userId = RequestUtils.getUserId(request);
        return Result.success(fileManager.uploadUserAvatar(file, userId));
    }

    //endregion
}
